package sipus.action.maintenance;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.util.GenericAutowireComposer;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Center;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Label;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Row;
import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.Rows;
import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.South;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Toolbar;
import org.zkoss.zul.Toolbarbutton;
import org.zkoss.zul.Window;

import sipus.action.master.helper.RevisiHelper;
import sipus.common.Common;
import sipus.common.CommonPrivilages;
import sipus.common.DesEncrypter;
import sipus.database.dao.DaoFactory;
import sipus.database.dao.TbmuserDao;
import sipus.database.hibernate.HibernateUtil;
import sipus.database.model.Tbmrole;
import sipus.database.model.Tbmuser;


public class TbmuserAction extends GenericAutowireComposer {

	/**
	 * 
	 */
	private static final long serialVersionUID = 7070962748923355504L;
	private Window addWindow;
	private Grid grid;

	private Textbox searchnama;
	private Textbox userNama;
	private Textbox userid;
	private Textbox userPassword;
	private Combobox userRole;
	private Checkbox userShow;
	private Combobox searchrole;

	private boolean edit = false;
	private boolean delete = false;

	private Tbmuser tbmuser;
	private Tbmrole tbmrole;
	private Toolbarbutton add;

	private DesEncrypter desEncrypter = new DesEncrypter(Common.DES_PASS_PHRASE);

	@Override
	public void doAfterCompose(Component comp) throws Exception {
		// TODO Auto-generated method stub
		super.doAfterCompose(comp);

		if (session.getAttribute("usersTemp") == null
				|| !CommonPrivilages.checkPrevilages(CommonPrivilages.READ)) {
			session.removeAttribute("usersTemp");
			execution.sendRedirect("/logoff");
			return;
		}

		add.setVisible(CommonPrivilages
				.checkPrevilages(CommonPrivilages.CREATE));
		add.setTooltiptext("Tambah");

		edit = CommonPrivilages.checkPrevilages(CommonPrivilages.UPDATE);
		delete = CommonPrivilages.checkPrevilages(CommonPrivilages.DELETE);

		if (Common.getCurrentUser().getUserRole().getRoleId().equals("am")) {
			Common.insertCombo(userRole = new Combobox(), "roleName",
					Tbmrole.class, Restrictions.ne("roleId", "am"));
			Common.insertCombo(searchrole, "roleName", Tbmrole.class);
		} else {
			Common.insertCombo(userRole = new Combobox(), "roleName",
					Tbmrole.class, Restrictions.eq("roleId", "Dosen"));
			Common.insertCombo(searchrole, "roleName", Tbmrole.class,
					Restrictions.ne("roleId", "am"));
		}

		onSearchDefault(null);
	}

	class UserRenderer implements RowRenderer {

		@Override
		public void render(final Row arg0, Object arg1) throws Exception {
			// TODO Auto-generated method stub
			final Tbmuser tbmuser = (Tbmuser) arg1;

			new Label(tbmuser.getUserId()).setParent(arg0);
			RevisiHelper.createNewRevisi(Tbmuser.class, tbmuser,
					tbmuser.getUserNama()).setParent(arg0);
			new Label(tbmuser.getUserRole().getRoleName()).setParent(arg0);

			Hbox toolbar = new Hbox();
			Toolbarbutton button = new Toolbarbutton("", "/img/edit.gif");
			button.setTooltiptext("Rubah Data");
			button.setVisible(edit);
			button.addEventListener("onClick", new EventListener() {
				@Override
				public void onEvent(Event event) throws Exception {
					init(tbmuser);
					addWindow.setVisible(true);
					addWindow.onModal();
				}

			});
			button.setParent(toolbar);

			button = new Toolbarbutton("", "/img/delete.gif");
			button.setTooltiptext("Hapus Data");
			button.setVisible(delete);
			button.addEventListener("onClick", new EventListener() {
				@Override
				public void onEvent(Event event) throws Exception {
					Messagebox.show("Apakah yakin ingin menghapus data ini ?",
							"Question", Messagebox.OK | Messagebox.CANCEL,
							Messagebox.QUESTION, new EventListener() {

								@Override
								public void onEvent(Event event)
										throws Exception {
									int i = new Integer(event.getData()
											.toString());
									if (i == Messagebox.OK) {
										try {
											TbmuserDao tbmuserDao = DaoFactory
													.getInstance()
													.getTbmuserDao();
											// agamaDao.beginTransaction();
											tbmuserDao.delete(tbmuserDao
													.merge(tbmuser));
											// agamaDao.commitTransaction();
											onSearchDefault(event);
										} catch (Exception e) {
											e.printStackTrace();
											Messagebox
													.show("Data ini tidak dapat dihapus .., karena berelasi dengan data lainnya, error-nya adalah sbagai berikut:"
															+ e.getMessage());
										}

									}

								}
							});

				}
			});
			button.setParent(toolbar);
			toolbar.setParent(arg0);
		}

	}

	public void onAdd(Event event) throws Exception {
		init(new Tbmuser());
		addWindow.setVisible(true);
		addWindow.onModal();
	}

	private void init(Tbmuser tbmuser) {
		this.tbmuser = tbmuser;
		addWindow.setTitle("Pendataan Pengguna");
		Common.clear(addWindow);
		Borderlayout borderlayout = new Borderlayout();
		Center center = new Center();
		center.setParent(borderlayout);
		center.setFlex(true);
		Grid grid = new Grid();
		grid.setParent(center);
		grid.setWidth("100%");
		grid.setHeight("100%");
		// grid.setOddRowSclass("non-odd");

		Rows rows = new Rows();
		rows.setParent(grid);

		Row row = new Row();
		row.setStyle("border:0px;background: transparent;");
		row.setParent(rows);
		row.appendChild(new Label("User id"));
		row.appendChild(userid = new Textbox(tbmuser.getUserId() == null ? ""
				: tbmuser.getUserId()));
		userid.setCols(40);

		row = new Row();
		row.setStyle("border:0px;background: transparent;");
		row.setParent(rows);
		row.appendChild(new Label("Nama"));
		row.appendChild(userNama = new Textbox(
				tbmuser.getUserNama() == null ? "" : tbmuser.getUserNama()));
		userNama.setCols(40);

		row = new Row();
		row.setStyle("border:0px;background: transparent;");
		row.setParent(rows);
		row.appendChild(new Label("Password"));
		row.appendChild(userPassword = new Textbox(
				tbmuser.getUserPassword() == null ? "" : tbmuser
						.getUserPassword()));

		if (tbmuser.getIs_encripted() != null && tbmuser.getIs_encripted()) {
			try {
				userPassword.setValue(tbmuser.getUserPassword() == null ? ""
						: desEncrypter.decrypt(tbmuser.getUserPassword()));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		userPassword.setType("password");
		userPassword.setCols(40);

		// row = new Row();
		// row.setStyle("border:0px;background: transparent;");
		// row.setParent(rows);
		// row.appendChild(new Label("Ter-enkrpsi"));
		// row.appendChild(isEncripted = new Checkbox());
		// isEncripted.setChecked(tbmuser.getIs_encripted() != null
		// && tbmuser.getIs_encripted());

		row = new Row();
		row.setStyle("border:0px;background: transparent;");
		row.setParent(rows);
		row.appendChild(new Label("Role"));
		Common.selectComboItem(userRole, tbmuser.getUserRole() == null ? null
				: tbmuser.getUserRole());
		row.appendChild(userRole);
		userRole.setCols(40);

		row = new Row();
		row.setStyle("border:0px;background: transparent;");
		row.setParent(rows);
		row.appendChild(new Label("Show"));
		row.appendChild(userShow = new Checkbox());
		userShow.setChecked(tbmuser.getUserShow() == null ? false : tbmuser
				.getUserShow().equals(1));
		userShow.addEventListener("onCheck", new EventListener() {
			@Override
			public void onEvent(Event arg0) throws Exception {
				if (userShow.isChecked()) {
					userShow.setAttribute("myValue", 1);
				} else {
					userShow.setAttribute("myValue", 0);
				}
			}
		});

		South south = new South();
		south.setFlex(true);
		south.setParent(borderlayout);

		Toolbar toolbar = new Toolbar();
		toolbar.setHeight("30px");
		toolbar.setParent(south);
		Toolbarbutton cancel = new Toolbarbutton("Batal", "/img/cancel.gif");
		cancel.setTooltiptext("Tutup");
		cancel.addEventListener("onClick", new EventListener() {
			@Override
			public void onEvent(Event event) throws Exception {
				addWindow.setVisible(false);
			}
		});
		cancel.setParent(toolbar);
		Toolbarbutton save = new Toolbarbutton("Simpan", "/img/save.gif");
		save.setTooltiptext("Simpan");
		save.addEventListener("onClick", new EventListener() {
			@Override
			public void onEvent(Event event) throws Exception {
				if (onSave(event)) {
					onSearchDefault(null);
					addWindow.setVisible(false);
				}
			}
		});
		save.setParent(toolbar);
		borderlayout.setParent(addWindow);

	}

	public boolean onSave(Event event) throws Exception {
		if (userNama.getValue().trim().equals("")) {
			Messagebox.show("Kode pengguna harus diisi", "Peringatan",
					Messagebox.OK, Messagebox.EXCLAMATION);
			return false;
		}
		if (userPassword.getValue().trim().equals("")) {
			Messagebox.show("Password harus diisi", "Peringatan",
					Messagebox.OK, Messagebox.EXCLAMATION);
			return false;
		}
		if (userRole.getSelectedItem() == null) {
			Messagebox.show("Role harus dipilih", "Peringatan", Messagebox.OK,
					Messagebox.EXCLAMATION);
			return false;
		}

		boolean i = checkUser();
		if (i) {
			Messagebox
					.show("Username sudah terpakai, silahkan pilih username yang lain",
							"Peringatan", Messagebox.OK, Messagebox.EXCLAMATION);
			return false;
		}

		TbmuserDao tbmuserDao = DaoFactory.getInstance().getTbmuserDao();
		if (tbmuser.getUserId() != null) {
			tbmuser = tbmuserDao.load(tbmuser.getUserId());

		}

		tbmuser.setUserId(userid.getValue());
		tbmuser.setUserNama(userNama.getValue());
		tbmuser.setUserPassword(desEncrypter.encrypt(userPassword.getValue()));
		tbmuser.setIs_encripted(true);

		tbmuser.setUserRole((Tbmrole) userRole.getSelectedItem().getValue());
		tbmuser.setUserShow(userShow.isChecked() ? 1 : 0);

		if (tbmuser.getUserId() != null) {
			tbmuserDao.update(tbmuser);
		} else {
			tbmuserDao.save(tbmuser);
		}

		return true;
	}

	@SuppressWarnings("unchecked")
	public void onSearchDefault(Event event) {
		Session session = HibernateUtil.currentSession();

		List<Tbmuser> tbmuser = session
				.createCriteria(Tbmuser.class)
				.addOrder(Order.asc("userNama"))
				.add(Restrictions.ilike("userNama", searchnama.getValue()
						.trim(), MatchMode.ANYWHERE))
				.add(searchrole.getSelectedItem() == null ? Restrictions
						.sqlRestriction("1=1") : Restrictions.eq("userRole",
						searchrole.getSelectedItem().getValue()))
				.add(tbmrole == null || !tbmrole.getRoleName().equals("am") ? Restrictions
						.eq("userShow", 1) : Restrictions.sqlRestriction("1=1"))

				.setMaxResults(Common.MAX_RESULT).list();
		ListModel strset = new SimpleListModel(tbmuser);
		grid.setRowRenderer(new UserRenderer());
		grid.setModel(strset);

		grid.renderAll();
		// grid.setOddRowSclass("non-odd");

	}

	public Boolean checkUser() {

		Integer userCount = null;
		Session session = HibernateUtil.currentSession();
		userCount = ((Number) session
				.createCriteria(Tbmuser.class)
				.setProjection(Projections.count("id"))
				.add(Restrictions.eq("userId", userid.getValue().trim()))
				.add(this.tbmuser.getUserId() == null ? Restrictions
						.sqlRestriction("1=1") : Restrictions.ne("id",
						this.tbmuser.getUserId())).uniqueResult()).intValue();

		return !userCount.equals(0);
	}
}
